from flask import Blueprint, request, jsonify, current_app
from app.models.user import User
from app.extensions import db
import jwt
import re
import uuid
from datetime import datetime, timedelta,timezone  
from app.config import Config
from functools import wraps
from werkzeug.utils import secure_filename
import os

auth_bp = Blueprint('auth', __name__)

# 工具函数：验证token
def token_required(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        token = None
        auth_header = request.headers.get('Authorization')
        if auth_header and auth_header.startswith('Bearer '):
            token = auth_header.split(' ')[1]
        if not token:
            return jsonify({'message': 'Token缺失'}), 401
        try:
            data = jwt.decode(token, Config.JWT_SECRET_KEY, algorithms=['HS256'])
            current_user = User.query.filter_by(user_id=data['user_id']).first()
            if not current_user:
                return jsonify({'message': '用户不存在'}), 404
        except jwt.ExpiredSignatureError:
            return jsonify({'message': 'Token已过期'}), 401
        except:
            return jsonify({'message': 'Token无效'}), 401
        return f(current_user, *args, **kwargs)
    return decorated

# 工具函数：验证手机号/邮箱格式
def is_valid_phone(phone):
    return re.match(r'^1[3-9]\d{9}$', phone) is not None

def is_valid_email(email):
    return re.match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', email) is not None


# 1. 注册（支持手机号/邮箱作为username）
@auth_bp.route('/register', methods=['POST'])
def register():
    data = request.get_json()
    username = data.get('username')  # 手机号或邮箱
    password = data.get('password')
    nickname = data.get('nickname')

    # 验证参数
    if not username or not password:
        return jsonify({'message': '账号和密码不能为空'}), 400
    # 验证username是手机号或邮箱
    if not (is_valid_phone(username) or is_valid_email(username)):
        return jsonify({'message': '账号必须是手机号或邮箱'}), 400
    # 检查账号是否已存在
    if User.query.filter_by(username=username).first():
        return jsonify({'message': '账号已被注册'}), 400

    # 创建用户（手机号/邮箱存入username，同时单独存入phone/email字段）
    new_user = User(
        username=username,
        password=User.generate_hash(password),
        nickname=nickname if nickname else f'用户{uuid.uuid4().hex[:6]}',  # 默认昵称
        phone=username if is_valid_phone(username) else None,
        email=username if is_valid_email(username) else None
    )
    db.session.add(new_user)
    db.session.commit()

    return jsonify({
        'message': '注册成功',
        'user_id': new_user.user_id
    }), 201


# 2. 登录（账号+密码）
@auth_bp.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    user = User.query.filter_by(username=username).first()
    if not user:
        return jsonify({'message': '账号不存在'}), 404
    if not User.verify_hash(password, user.password):
        return jsonify({'message': '密码错误'}), 401

    print("JWT过期时间配置：", Config.JWT_ACCESS_TOKEN_EXPIRES)  # 应输出 2:00:00
    print("Token生成时间（UTC）：", datetime.now(timezone.utc))
    print("Token过期时间（UTC）：", datetime.now(timezone.utc) + Config.JWT_ACCESS_TOKEN_EXPIRES)
    # 生成token
    token = jwt.encode(
        {'user_id': user.user_id, 'exp': datetime.now(timezone.utc) + Config.JWT_ACCESS_TOKEN_EXPIRES},
        Config.JWT_SECRET_KEY,
        algorithm='HS256'
    )

    return jsonify({
        'token': token,
        'user_id': user.user_id,
        'nickname': user.nickname,
        'avatar_url': user.avatar_url
    }), 200


# 3. 密码找回（通过手机号/邮箱验证码，这里简化为“验证身份后重置”）
@auth_bp.route('/forgot-password', methods=['POST'])
def forgot_password():
    data = request.get_json()
    account = data.get('account')  # 手机号或邮箱
    new_password = data.get('new_password')

    # 验证账号存在
    user = None
    if is_valid_phone(account):
        user = User.query.filter_by(phone=account).first()
    elif is_valid_email(account):
        user = User.query.filter_by(email=account).first()
    if not user:
        return jsonify({'message': '手机号/邮箱未注册'}), 404

    # （实际项目需添加验证码验证步骤，这里跳过）
    user.password = User.generate_hash(new_password)
    db.session.commit()
    return jsonify({'message': '密码已重置'}), 200


# 4. 密码修改（需原密码验证）
@auth_bp.route('/change-password', methods=['POST'])
@token_required
def change_password(current_user):
    data = request.get_json()
    old_password = data.get('old_password')
    new_password = data.get('new_password')

    if not User.verify_hash(old_password, current_user.password):
        return jsonify({'message': '原密码错误'}), 400

    current_user.password = User.generate_hash(new_password)
    db.session.commit()
    return jsonify({'message': '密码修改成功'}), 200


# 5. 获取个人信息
@auth_bp.route('/profile', methods=['GET'])
@token_required
def get_profile(current_user):
    return jsonify({
        'user_id': current_user.user_id,
        'username': current_user.username,
        'nickname': current_user.nickname,
        'phone': current_user.phone,
        'email': current_user.email,
        'avatar_url': current_user.avatar_url,
        'gender': current_user.gender,
        'birthday': current_user.birthday.isoformat() if current_user.birthday else None
    }), 200


# 6. 修改个人信息（昵称、手机号、邮箱等）
@auth_bp.route('/profile', methods=['PUT'])
@token_required
def update_profile(current_user):
    data = request.get_json()
    # 昵称
    if 'nickname' in data:
        current_user.nickname = data['nickname']
    # 手机号（需验证唯一性）
    if 'phone' in data and data['phone']:
        if not is_valid_phone(data['phone']):
            return jsonify({'message': '手机号格式错误'}), 400
        if User.query.filter_by(phone=data['phone']).filter(User.user_id != current_user.user_id).first():
            return jsonify({'message': '手机号已被使用'}), 400
        current_user.phone = data['phone']
    # 邮箱（需验证唯一性）
    if 'email' in data and data['email']:
        if not is_valid_email(data['email']):
            return jsonify({'message': '邮箱格式错误'}), 400
        if User.query.filter_by(email=data['email']).filter(User.user_id != current_user.user_id).first():
            return jsonify({'message': '邮箱已被使用'}), 400
        current_user.email = data['email']
    # 性别
    if 'gender' in data and data['gender'] in ['男', '女', '保密']:
        current_user.gender = data['gender']
    # 生日
    if 'birthday' in data and data['birthday']:
        try:
            current_user.birthday = datetime.strptime(data['birthday'], '%Y-%m-%d').date()
        except:
            return jsonify({'message': '生日格式错误（需YYYY-MM-DD）'}), 400

    db.session.commit()
    return jsonify({'message': '个人信息更新成功'}), 200


# 7. 头像上传
@auth_bp.route('/avatar', methods=['POST'])
@token_required
def upload_avatar(current_user):
    # 检查是否有文件
    if 'avatar' not in request.files:
        return jsonify({'message': '未上传文件'}), 400
    file = request.files['avatar']
    if file.filename == '':
        return jsonify({'message': '文件名为空'}), 400

    # 验证文件类型
    allowed_extensions = {'png', 'jpg', 'jpeg', 'gif'}
    if '.' not in file.filename or file.filename.split('.')[-1].lower() not in allowed_extensions:
        return jsonify({'message': '仅支持png、jpg、jpeg、gif格式'}), 400

    # 保存文件（实际项目建议用云存储，这里存本地）
    upload_folder = os.path.join(current_app.root_path, 'static/avatars')
    os.makedirs(upload_folder, exist_ok=True)
    filename = f"{current_user.user_id}_{uuid.uuid4().hex[:8]}.{file.filename.split('.')[-1].lower()}"
    file_path = os.path.join(upload_folder, filename)
    file.save(file_path)

    # 更新用户头像URL
    current_user.avatar_url = f'/static/avatars/{filename}'
    current_user.avatar_update_time = datetime.now(timezone.utc)
    db.session.commit()

    return jsonify({
        'message': '头像上传成功',
        'avatar_url': current_user.avatar_url
    }), 200